home *** CD-ROM | disk | FTP | other *** search
/ The Arcade BBS / arcadebbs.zip / arcadebbs / bbstools / WWIV Mods / WWIVMOD.ZIP / FILGRE01.MOD < prev    next >
Encoding:
Text File  |  1993-08-10  |  18.8 KB  |  543 lines

  1. Mon Jul 05 18:14:08 1993
  2. ┌───────────────────────────────────────────────────────────────────────────┐
  3. │ Mod Name: FILGRE01  (Filo05 meets Greeny02)      Authors: Filo and Greeny │
  4. │ Difficulty: Easy - Medium (mostly block read)    Date: June 21, 1993      │
  5. │ WWIV Version: Updated for use with WWIV 4.22!                             │
  6. │ Description:  Allows you to organize your chains by groups and have       │
  7. │ neater looking menus. Also adds a timelock to your doors, and a bar       │
  8. │ graph showing comparative usage for each on-liner.                        │
  9. └───────────────────────────────────────────────────────────────────────────┘
  10.  
  11.    I liked the combination of these two mods togeather so much, that I decided
  12. to put them togeather in one mod for those novice modders out there like me. I
  13. did nothing special, and all credit goes to Filo and Greeny for writing such
  14. great mods, and for allowing me to combine the two togeather.
  15.  
  16. NOTES FROM THE AUTHORS:
  17.  
  18. FROM FILO ABOUT FILO05:
  19.  
  20. Nasti Habitz deserves credit for thinking of this mod and for writing much of
  21. the code which is used here.  He developed the mod, uploaded it to my board
  22. and some 6 months later I tried installing it in 4.20.  Disaster!  Not only
  23. does much of the mod go in new places, but also the mod did not work as
  24. written.  UT Prof and I spent a whole afternoon trying to change parameters
  25. and get it to work, but to no avail.  After much trial and error effort,
  26. the mod now works and is in use at The Dragon's Den.
  27.  
  28. FROM GREENY ABOUT GREENY02:
  29.  
  30. This mod evolved out of a mutant crossbreeding between somebody's onliner
  31. timelock mod, and the mod that puts a purple box around transfers.  Now it's
  32. a boxed, color-coded timelock mod with bar graphs of comparative usage for
  33. each onliner.  Tacky, eh?  What else are onliners for?
  34.  
  35. You set a timelock for each onliner.  I.E. this onliner can only be played
  36. from 11:00 pm to 3:00 am.  This is done in //chainedit, and yes I know
  37. entering it in minutes from midnight is annoying.  Sheer lazines on my part.
  38. I made this entire mod under protest and only decided to release it because
  39. it had been so much work.  Anyway, all onliners that are currently
  40. accessible will show up as green to everyone with ansi.  If it's timelocked,
  41. it'll be dark red.  If someone tries to play a timelocked onliner, a message
  42. will appear informing them from when to when the onliner is accessible.  If
  43. they select a green one, it'll just load it up and go.  If you leave the on
  44. and off times at midnight (the default), that onliner will always be green.
  45. If start time is after end time, the available time will continue through
  46. midnight and into the next day.
  47.  
  48. For those users who don't have ansi, the box will be made out of stuff like
  49. plusses and minuses.  Plus, they can tell timelocked onliners by the
  50. asterisk that appears in the appropriate row all the way to the right.
  51.  
  52. The bar graphs should be self explanatory.  To zero out the count, remove
  53. and re-install the onliner.  Why you'd want to is beyond me, but it can be
  54. done.
  55.  
  56. Oh, by the way: exemption 16 exempts people from the timelock.  If you're
  57. already using this for something else, change the #define...
  58.  
  59. A program called subcnvt is included to convert your chains.dat file to the
  60. new format.  Yes, it is yet another use for black dragon's convert
  61. program.  Somebody give him a medal or something.  To use the
  62. program, block read it out, compile it, go to your data directory,
  63. rename chains.dat chains.old, and subcnvt chains.old chains.dat.  Then if
  64. you're feeling industrious, delete chains.old.
  65.  
  66. NOTE FROM MARK:
  67.  
  68. I did not use the subcnvt program, and don't know if it will work with both
  69. of these mods combined.  All I did was copy down all my chain configurations,
  70. deleted them, did the mod, and inserted the chains again in chainedit.
  71.  
  72. UPDATE FOR 4.22 NOTE:
  73.  
  74. Some changes needed to be made for 4.22.  I did not remove all of the strings
  75. in this mod, I will leave that to the SysOp's installing it.  String #119 must
  76. be modified though, to reflect the changes in Chainedit.
  77.  
  78. DISCLAIMER:  The authors (or myself) are not responsible for what the
  79. installation of this mod may do to your software, hardware, data
  80. files, etc.  I "personally" use this combination on a fairly well
  81. modified 4.22 version of WWIV, and have experienced no problems.
  82.  
  83. KEY }  == Existing code   ++ Add this line   += Change this line
  84.  
  85. Files to be modified:
  86.  
  87. VARDEC.H  --> chainfilerec
  88. BBSUTL1.C --> void do_chains / void show_chains / void run_chains
  89. CHNEDIT.C --> void modify_chain / void insert_chain
  90.  
  91. ************  B A C K   U P   Y O U R   S O U R C E  ************
  92.  
  93. STEP 1:
  94.  
  95. Load up VARDEC.H and change/add the following:
  96.  
  97. == /* DATA FOR OTHER PROGRAMS AVAILABLE */
  98. == typedef struct {
  99. ==         char            filename[81],           /* filename for .chn file */
  100. ==                         description[81];        /* description of it */
  101. ==         unsigned char   sl,                     /* seclev restriction */
  102. ==                         ansir;                  /* if ANSI required */
  103. +=         unsigned short  ar,                     /* AR restriction */
  104. ++                         lowtime,
  105. ++                         hightime,
  106. ++                         usage,
  107. ++                         grp;
  108. == } chainfilerec;
  109.  
  110. Farther down find:
  111.  
  112. == #define exempt_post 0x08
  113. ++ #define exempt_timelock 0x10
  114.  
  115. Save VARDEC.H
  116.  
  117. STEP 2:
  118.  
  119. Load up BBSUTL1.C and either comment out or delete void do_chains and
  120. replace it with this one:
  121.  
  122. void do_chains()
  123. {
  124.   int map[99],mapp,i,i1,ok,done,AR_L;
  125.   char s[81],s1[81],ch,*ss;
  126.   chainfilerec c;
  127.   unsigned short groupid;                 /*  <-- New variable */
  128.   printfile("GROUP");
  129.   prt(2,"Which Area (A-P, Q=Quit) ? ");
  130.   ch=onek("ABCDEFGHIJKLMNOPQ");
  131.   if(ch=='Q')
  132.     return;
  133.   groupid=1 << (ch-'A');
  134.   mapp=0;
  135.   for (i=0; i<10; i++)
  136.     odc[i]=0;
  137.   for (i=0; i<numchain; i++) {
  138.     ok=1;
  139.     c=chains[i];
  140.     if ((c.ansir & ansir_ansi) && (!okansi()))
  141.       ok=0;
  142.     if ((c.ansir & ansir_no_300) && (modem_speed==300))
  143.       ok=0;
  144.     if (c.sl>thisuser.sl)
  145.       ok=0;
  146.     if ((c.ar) && incom)
  147.       ok=1;
  148.     if (((c.ar & thisuser.ar)==0) && (c.ar))
  149.       ok=0;
  150.     if ((c.grp & groupid)==0)               /*  <-- Check for a group */
  151.       ok=0;                                 /*  <-- match here.       */
  152.   
  153.     if (ok) {
  154.       map[mapp++]=i;
  155.       if ((mapp % 10) ==0)
  156.         odc[mapp/10 -1]='0'+(mapp/10);
  157.     }
  158.   }
  159.   if (mapp==0) {
  160.     nl();
  161.     nl();
  162.     pl("Sorry, no external programs available.");
  163.     nl();
  164.     return;
  165.   }
  166.   if (mapp==1) {
  167.     run_chain(map[0]);
  168.    return;
  169. }
  170.   show_chains(&mapp,map);
  171.   done=0;
  172.   
  173.   do {
  174.     prt(2,"Which (Q=Quit, ?=List, N=New Group) : ");  /*  <-- Add N option */
  175.     ss=mmkey(2);
  176.     i=atoi(ss);
  177.     if ((i>0) && (i<=mapp)) {
  178.       done=0;
  179.       run_chain(map[i-1]);
  180.     } else
  181.       if (strcmp(ss,"Q")==0)
  182.         done=1;
  183.       else
  184.         if (strcmp(ss,"?")==0)
  185.           show_chains(&mapp,map);
  186.       else
  187.         if (strcmp(ss,"N")==0) {
  188.           do_chains();
  189.           return;
  190.     }
  191.   } while ((!hangup) && (!done));
  192. }
  193.  
  194. Next, delete the entire functions void show_chains and void run_chains
  195. and replace them with the following (one HUGE block read):
  196.  
  197.  
  198. void show_chains(int *mapp, int *map)
  199. {
  200.   int abort,next,i,i1,j,k,macks=0,padington;
  201.   char s[81],tempomatic[10];
  202.  
  203.   abort=0;
  204.   for(i=0;i<*mapp;i++)
  205.     if(chains[map[i]].usage>macks) macks=chains[map[i]].usage;
  206.   nl();
  207.   osan("\0031    Title",&abort,&next);
  208.   for(i=0;i<37;i++) osan(" ",&abort,&next);
  209.   pla(" Popularity    Times run",&abort);
  210.   osan(okansi() ? "\0033┌──┬" : "+--+",&abort,&next);
  211.   for(i=0;i<42;i++) osan(okansi() ? "─" : "-",&abort,&next);
  212.   osan(okansi() ? "┬" : "+",&abort,&next);
  213.   for(i=0;i<10;i++) osan(okansi() ? "─" : "-",&abort,&next);
  214.   pla(okansi() ? "┬─┐" : "+-+" ,&abort);
  215.   for (i=0; (i<*mapp) && (!abort) && (!hangup); i++) {
  216.     strcpy(s,okansi() ? "\0033│\0032" : "|");
  217.     if(i<9) strcat(s," ");
  218.     itoa(i+1,tempomatic,10);
  219.     strcat(s,tempomatic);
  220.     osan(s,&abort,&next);
  221.     osan(okansi() ? "\0033│ " : "| ",&abort,&next);
  222.     k=1;
  223.  
  224.   if((chains[map[i]].lowtime!=chains[map[i]].hightime) &&
  225.     !(thisuser.exempt & exempt_timelock))
  226.     if(chains[map[i]].hightime>chains[map[i]].lowtime) {
  227.       if((timer()<=(chains[map[i]].lowtime*60.0)) ||
  228.     (timer()>=(chains[map[i]].hightime*60.0))) k=0;
  229.     } else {
  230.       k=0;
  231.       if((timer()>(chains[map[i]].lowtime*60.0)) ||
  232.     (timer()<(chains[map[i]].hightime*60))) k=1;
  233.     }
  234.     if(!abort && okansi()) {
  235.       if(k) setc(10);
  236.       else setc(4);
  237.     }
  238.     osan(chains[map[i]].description,&abort,&next);
  239.     for(padington=0,j=0;j<strlen(chains[map[i]].description); j++)
  240.       if(chains[map[i]].description[j]==3) padington+=2;
  241.     for(j=strlen(chains[map[i]].description); j<=40+padington;j++)
  242.       osan(" ",&abort,&next);
  243.     osan(okansi() ? "\0033│\0037" : "|",&abort,&next);
  244.     j=0;
  245.     if(chains[map[i]].usage)
  246.       if((macks/chains[map[i]].usage)*10)
  247.     for(j=1;j<=((float) chains[map[i]].usage/macks)*10; j++)
  248.       osan(okansi() ? "▀" : "#",&abort,&next);
  249.     if(j==0) j++;
  250.     while(++j<=11) osan(okansi() ? " " : ":",&abort,&next);
  251.     osan(okansi() ? "\0033│" : "|",&abort,&next);
  252.     if(okansi()) setc(4);
  253.     osan(k ? " " : "*",&abort,&next);
  254.     osan(okansi() ? "\0033│ \0031" : "| ",&abort,&next);
  255.     sprintf(s,"%05d",chains[map[i]].usage);
  256.     pla(s,&abort);
  257.   }
  258.   osan(okansi() ? "\0033└──┴" : "+--+",&abort,&next);
  259.   for(i=0;i<42;i++) osan(okansi() ? "─" : "-",&abort,&next);
  260.   osan(okansi() ? "┴" : "+",&abort,&next);
  261.   for(i=0;i<10;i++) osan(okansi() ? "─" : "-",&abort,&next);
  262.   pla(okansi() ? "┴─┘" : "+-+",&abort);
  263.   nl();
  264. }
  265.  
  266.  
  267. void run_chain(int cn)
  268. {
  269.   char s[255],s1[81],s2[81],s3[81];
  270.   int oc,f,blat;
  271.   unsigned int toph,topm,topf,both,botm,botf;
  272.   long l;
  273.  
  274.   blat=0;
  275.   if((chains[cn].lowtime!=chains[cn].hightime) &&
  276.     !(thisuser.exempt & exempt_timelock))
  277.     if(chains[cn].hightime>chains[cn].lowtime) {
  278.       if((timer()<=(chains[cn].lowtime*60.0)) ||
  279.          (timer()>=(chains[cn].hightime*60.0))) blat=1;
  280.     } else {
  281.     blat=1;
  282.     if((timer()>(chains[cn].lowtime*60.0)) ||
  283.       (timer()<(chains[cn].hightime*60.00))) blat=0;
  284.   }
  285.   if(blat) {
  286.     topf=botf=0;
  287.     toph=chains[cn].hightime/60;
  288.     topm=chains[cn].hightime-(60*toph);
  289.     if(!toph) toph=12;
  290.     if(chains[cn].hightime>=720) {
  291.       toph-=12;
  292.       topf=1;
  293.     }
  294.     both=chains[cn].lowtime/60;
  295.     botm=chains[cn].lowtime-(60*both);
  296.     if(!both) both=12;
  297.     if(chains[cn].lowtime>=720) {
  298.       both-=12;
  299.       botf=1;
  300.     }
  301.     ansic(1);
  302.     npr("\0031%s is only available from %d:%02d%cm to %d:%02d%cm\r\n",
  303.     chains[cn].description,both,botm,botf?'p':'a',toph,topm,topf?'p':'a');
  304.     sprintf(s2,"!Timelock on '%s'",chains[cn].description);
  305.     sysoplog(s2);
  306.     return;
  307.   }
  308.   chains[cn].usage++;
  309.   sprintf(s,"%sCHAINS.DAT",syscfg.datadir);
  310.   f=open(s,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  311.   write(f,(void *)chains, numchain * sizeof(chainfilerec));
  312.   close(f);
  313.   itoa(com_speed, s1, 10);
  314.   itoa(syscfg.primaryport,s2,10);
  315.   itoa(modem_speed, s3, 10);
  316.   stuff_in(s,chains[cn].filename,create_chain_file("CHAIN.TXT"),s1,s2,s3,"");
  317.   sprintf(s2,"!Ran '%s'",chains[cn].description);
  318.   sysoplog(s2);
  319.   oc=chatcall;
  320.   chatcall=0;
  321.   l=thisuser.sysstatus;
  322.   if (chains[cn].ansir & ansir_no_pause)
  323.     thisuser.sysstatus &= ~sysstatus_pause_on_page;
  324.   if (chains[cn].ansir & ansir_no_DOS) {
  325.     set_protect(0);
  326.     if (chains[cn].ansir & ansir_shrink)
  327.       shrink_out(s,1,0,1,1);
  328.     else
  329.       run_external(s);
  330.     topscreen();
  331.   } else
  332.     if (chains[cn].ansir & ansir_shrink)
  333.       shrink_out(s,1,1,1,1);
  334.     else
  335.       full_external(s,0,1);
  336.   thisuser.sysstatus = l;
  337.   chatcall=oc;
  338. }
  339.  
  340. Save BBSUTL1.C
  341.  
  342. STEP 3:
  343.  
  344. Load up CHNEDIT.C and make the following changes to void modify_chain:
  345.  
  346.  
  347. ==    outstr(get_string(118));
  348. ==    pl((c.ansir & ansir_local_only)?str_yes:srt_no);
  349. ++    npr("K. Switch on at : %d:%02d\r\n",c.lowtime/60,
  350. ++                c.lowtime-((c.lowtime/60)*60));
  351. ++    npr("L. Switch off at: %d:%02d\r\n",c.hightime/60,
  352. ++                c.hightime-((c.hightime/60)*60));
  353. ++    if (c.grp!=0) {
  354. ++ for (i=0; i<16; i++)
  355. ++    if ((1 << i) & c.grp)
  356. ++      s[0]='A'+i;
  357. ++      s[1]=0;
  358. ++   }
  359. ++   npr("M. Group        : %s\r\n",s);
  360. ==    nl();
  361. +=    prt(2,get_string(119));  /* Modify string 119 to read: Which (A-M,Q) ? */
  362. +=    ch=onek("QABCDEFGHIJKLM");
  363. ==    switch(ch) {
  364. ==      case 'Q':done=1; break;
  365.  
  366. In the switch(ch) cases, (see next to last line above) insert the
  367. following after Case J :
  368.  
  369.  
  370. ==          c.ansir &= ~ansir_local_only;
  371. ==        break;
  372. ++        case 'K':
  373. ++        nl();
  374. ++        prt(5,"Chain Low Time (Mins from midnight)? ");
  375. ++        input(s,4);
  376. ++        i=atoi(s);
  377. ++        if(i>=0 && i<24*60) c.lowtime=i;
  378. ++        break;
  379. ++      case 'L':
  380. ++        nl();
  381. ++        prt(5,"Chain High Time (Mins from midnight)? ");
  382. ++        input(s,4);
  383. ++        i=atoi(s);
  384. ++        if(i>=0 && i<24*60) c.hightime=i;
  385. ++        break;
  386. ++    case 'M':
  387. ++        nl();
  388. ++        prt(2,"New group (A-P) ? ");
  389. ++        ch2=onek("ABCDEFGHIJKLMNOP");
  390. ++        c.grp=1 << (ch2-'A');
  391. ++        break;
  392. ==    }
  393. ==  } while ((!done) && (!hangup));
  394.  
  395. The next function to modify in is void insert_chain(int n).  Add the
  396. following three lines...
  397.  
  398. ==  c.ansir=0;
  399. ++  c.lowtime=0;
  400. ++  c.hightime=0;
  401. ++  c.usage=0;
  402. ==  chains[n]=c;
  403.  
  404. Save CHNEDIT.C   Compile your source, and while waiting, write Filo
  405. and Greeny a little thank you note for these great mods!
  406.  
  407. STEP 4:
  408.  
  409. Block read out and compile the subcnvt program which follows.  You need to
  410. use it on your chains.dat file in the data directory.
  411. Usage: subcnvt oldfile newfile. (READ NOTE FROM MARK ABOVE)
  412.  
  413.  
  414.  
  415. /* Begin subcnvt.c */
  416.  
  417. /*  CONVERT USERLIST PROGRAM */
  418. /*  Written by The Black Dragon, 1989 */
  419. /*  Mangled by Greeny to do something totally different. */
  420.  
  421. #include <stdio.h>
  422. #include <string.h>
  423. #include <mem.h>
  424. #include <io.h>
  425. #include <fcntl.h>
  426. #include <sys\stat.h>
  427. struct {char f[81],d[81],s,an;
  428.     unsigned ar,l,h,u;} new;
  429. struct {char f[81],d[81],s,an;
  430.     unsigned ar;} old;
  431. void main(int argc, char *argv[])
  432. {
  433.   int f,g,i;
  434.   unsigned int loop,num=0;
  435.   unsigned long len;
  436.  
  437.   if (argc<3) {
  438.     printf("\nRequires 2 parameters.\n");
  439.     printf("Usage: SUBCNVT oldfile newfile \n");
  440.     exit(0);
  441.   }
  442.   if ((f=open(argv[1],O_RDWR|O_BINARY,S_IREAD|S_IWRITE))<=0) {
  443.     printf("\nCould not open chain list %s\n",argv[1]);
  444.     abort();
  445.   }
  446.   if ((g=open(argv[2],O_RDWR|O_BINARY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE))<=0) {
  447.     printf("\nCould not open output file %s\n",argv[2]);
  448.     abort();
  449.   }
  450.   printf("\n\nSize of old record %d",sizeof(old));
  451.   printf("\nSize of new record %d\n\n",sizeof(new));
  452.  
  453.   len=filelength(f);
  454.   num=(len/sizeof(old))+!(len%sizeof(old));
  455.   for (loop=0;loop<num;loop++) {
  456.     if (sizeof(old)==read(f,&old,sizeof(old))) {
  457.     printf("\015Processing user #%u of %u",loop,num-1);
  458.  
  459.     memset(&new,0,sizeof(new));     /* Nice to clear out garbage */
  460.     strcpy(new.f,old.f);          /* Now copy all data over    */
  461.     strcpy(new.d,old.d);
  462.     new.s=old.s;
  463.     new.an=old.an;
  464.     new.ar=old.ar;
  465.     new.l=new.h=new.u=0;
  466.     write(g,&new,sizeof(new));      /* record converted here */
  467.     }
  468.   }
  469.   close(f);
  470.   close(g);
  471. }
  472.  
  473. /* End subcnvt.c */
  474.  
  475. STEP 5:
  476.  
  477. If you used subcnvt and it worked, all you need to do is go into
  478. chainedit and add the GROUP id's to your chains.  If your like me and
  479. just deleted them (your chains) go into chainedit and reinstall them.
  480. You will also need a GROUP.ANS and a GROUP.MSG in G-Files indicating the
  481. menu you want the users to see.  Filo's is included here (from The
  482. Draw) as a sample.
  483.  
  484.  
  485. Group.MSG
  486.  
  487.                 *******                           *******
  488.                   |||     THE DRAGON'S DEN          |||
  489.                   |||     Chain Group Menu          |||
  490.                   |||                               |||                  
  491.                   |||     Mod:  Filo05.mod          |||
  492.                   |||                               |||
  493.        ┌──────────────────────────────────────────────────────┐
  494.        │    A.  Access to Other Networks                      │
  495.        │          FidoNet, Vnet                               │
  496.        │    B.  Utility Modes                                 │
  497.        │          FindBoss, Bimodem, FreeDL                   │
  498.        │    C.  Adventure Games                               │
  499.        │          Numerous Games Here                         │
  500.        │    D.  Word Games                                    │
  501.        │          HangMan, Firing Squad, Word Scramble        │
  502.        │    E.  Other Games                                   │
  503.        │                                                      │
  504.        └──────────────────────────────────────────────────────┘
  505.  
  506.  
  507. Group.ANS
  508.                  ▄▄▄▄▄▄▄                   ▄▄▄▄▄▄▄
  509.                   ░▒▓▒░  The Dragon's Den   ░▒▓▒░
  510.                   ░▒▓▒░   Chain Group Menu  ░▒▓▒░
  511.                   ░▒▓▒░                     ░▒▓▒░
  512.                   ░▒▓▒░   Mod: Habitz01     ░▒▓▒░
  513.                   ░▒▓▒░                     ░▒▓▒░
  514.      ┌────────────────────────────────────────────────────────┐
  515.      │      A.  Access to Other Networks                      │
  516.      │            FidoNet, Vnet                               │
  517.      │      B.  Utility Modes                                 │
  518.      │            FindBoss, Bimodem, FreeDL                   │
  519.      │      C.  Adventure Games                               │
  520.      │            Numerous games here                         │
  521.      │      D.  Word Games                                    │
  522.      │            Firing Squad, HangMan, Word Scramble, etc   │
  523.      │      E.  Other Games                                   │
  524.      │            FoodFite, Milliways, and many others        │
  525.      └────────────────────────────────────────────────────────┘
  526.  
  527. THAT'S IT!  Make your menus any way you want them.  When the user hits
  528. ".", they will get the menu like above.  When they select the letter
  529. for the area they want, they will see a sub menu.  Here is an example
  530. of what the sub menu could look like:
  531.  
  532.  
  533.     Title                                      Popularity    Times run
  534. ┌──┬──────────────────────────────────────────┬──────────┬─┐
  535. │ 1│ BBS Checkers                             │▀         │ │ 00002
  536. │ 2│ Global Wars                              │▀▀▀▀▀▀▀▀  │ │ 00010
  537. │ 3│ Triple Yahtzee                           │▀▀▀▀▀     │ │ 00007
  538. │ 4│ HiRoll Dice                              │▀▀▀▀▀▀▀▀▀ │ │ 00011
  539. │ 5│ Greedy Dice                              │▀▀▀▀▀▀▀▀▀▀│ │ 00012
  540. │ 6│ BBS Chess                                │▀▀▀       │ │ 00004
  541. └──┴──────────────────────────────────────────┴──────────┴─┘
  542.  
  543.